#region Using Statements
using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.GamerServices;
using System.Collections.Generic;
using pds2.XArena;
#endregion

namespace QuizArena
{
    /// <summary>
    /// This menu screen displays a list of available network sessions,
    /// and lets the user choose which one to join.
    /// </summary>
    class TelaDeEscolherServidor : TelaDeMenu
    {
        #region Fields

        const int MaxSearchResults = 8;

        AvailableNetworkSessionCollection availableSessions;

        #endregion

        #region Initialization


        /// <summary>
        /// Constructs a menu screen listing the available network sessions.
        /// </summary>
        public TelaDeEscolherServidor(AvailableNetworkSessionCollection availableSessions)
            : base(Resources.JoinSession)
        {
            this.availableSessions = availableSessions;

            foreach (AvailableNetworkSession availableSession in availableSessions)
            {
                // Create menu entries for each available session.
                ItemDeMenu menuEntry = new ItemDeMenuParaSessaoDisponivel(availableSession);
                menuEntry.Selecionado += AvailableSessionMenuEntrySelected;
                ItensDeMenu.Add(menuEntry);

                // Matchmaking can return up to 25 available sessions at a time, but
                // we don't have room to fit that many on the screen. In a perfect
                // world we should make the menu scroll if there are too many, but it
                // is easier to just not bother displaying more than we have room for.
                if (ItensDeMenu.Count >= MaxSearchResults)
                    break;
            }

            // Add the Back menu entry.
            ItemDeMenu backMenuEntry = new ItemDeMenu(Resources.Back);
            backMenuEntry.Selecionado += BackMenuEntrySelected;
            ItensDeMenu.Add(backMenuEntry);

            PosicaoMenus = new Vector2(PosicaoMenus.X, PosicaoMenus.Y + 50);
        }


        #endregion
           
        #region Event Handlers


        /// <summary>
        /// Event handler for when an available session menu entry is selected.
        /// </summary>
        void AvailableSessionMenuEntrySelected(object sender, EventArgs e)
        {
            // Which menu entry was selected?
            ItemDeMenuParaSessaoDisponivel menuEntry = (ItemDeMenuParaSessaoDisponivel)sender;
            AvailableNetworkSession availableSession = menuEntry.AvailableSession;

            try
            {
                // Begin an asynchronous join network session operation.
                IAsyncResult asyncResult = NetworkSession.BeginJoin(availableSession,
                                                                    null, null);

                // Activate the network busy screen, which will display
                // an animation until this operation has completed.
                TelaDeRedeOcupada busyScreen = new TelaDeRedeOcupada(asyncResult);

                busyScreen.OperacaoConcluida += JoinSessionOperationCompleted;

                GerenciadorDeTelas.AdicionarTela(busyScreen);
            }
            catch (NetworkException exception)
            {
                GerenciadorDeTelas.AdicionarTela(new CaixaDeMensagemDeErroNaRede(exception));
            }
            catch (GamerPrivilegeException exception)
            {
                GerenciadorDeTelas.AdicionarTela(new CaixaDeMensagemDeErroNaRede(exception));
            }
        }


        /// <summary>
        /// Event handler for when the asynchronous join network session
        /// operation has completed.
        /// </summary>
        void JoinSessionOperationCompleted(object sender, OperacaoCompleta e)
        {
            try
            {
                // End the asynchronous join network session operation.
                NetworkSession networkSession = NetworkSession.EndJoin(e.AsyncResult);

                AssociadorDeEventos associadorDeEventos = new AssociadorDeEventos(networkSession, GerenciadorDeTelas);
                networkSession = associadorDeEventos.AssociarEventosDaSessao();

                //SelecaoNomeElementoMultiplayer sl = new SelecaoNomeElementoMultiplayer(
                //    GerenciadorDeTelas, networkSession);
                
                //sl.HookSessionEvents();

                // Create a component that will manage the session we just joined.
                ComponenteDeSessaoDeRede.Create(GerenciadorDeTelas, networkSession);

                // Go to the lobby screen.
                List<Tela> telasAnteriores = new List<Tela>();
                telasAnteriores.Add(new TelaDeFundo());
                telasAnteriores.Add(new TelaDoMenuPrincipal());
                GerenciadorDeTelas.AdicionarTela(new TelaPersonagemQA(telasAnteriores, false, networkSession));

                availableSessions.Dispose();
            }
            catch (NetworkException exception)
            {
                GerenciadorDeTelas.AdicionarTela(new CaixaDeMensagemDeErroNaRede(exception));
            }
            catch (GamerPrivilegeException exception)
            {
                GerenciadorDeTelas.AdicionarTela(new CaixaDeMensagemDeErroNaRede(exception));
            }
        }


        /// <summary>
        /// Event handler for when the Back menu entry is selected.
        /// </summary>
        void BackMenuEntrySelected(object sender, EventArgs e)
        {
            availableSessions.Dispose();

            SairDaTela();
        }


        #endregion
    }
}
